package umich.max.geolocation.featextract.ner;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;

import max.nlp.dal.blog.blogger.BloggerBlog;
import max.nlp.dal.blog.blogger.BloggerDB;
import max.nlp.dal.blog.blogger.BloggerPost;
import max.nlp.util.MapSorter;
import max.nlp.wrappers.ml.weka.WekaFeatureExtractor;
import umich.max.geolocation.geonames.Geonames;

public class MostProbableNStatesExtractor extends
		WekaFeatureExtractor<String, Integer> {

	private static String prefix = "mpLocs";
	private Geonames geonames = new Geonames();
	private final int N = 3;
	private static HashMap<String, Integer> strToIntConverter = new HashMap<String, Integer>();
	private static Integer currentInt = 0;

	public MostProbableNStatesExtractor() {
		super(prefix);
	}

	public HashMap<String, Integer> extractFeaturesForObject(Object item) {
		BloggerBlog blog = (BloggerBlog) item;
		HashMap<String, Integer> topStates = new HashMap<String, Integer>();

		HashMap<String, Integer> stateCounts = new HashMap<String, Integer>();
		for (BloggerPost post : blog.getPosts()) {
			List<String> locations = post.getLocations();
			if (!locations.isEmpty()) {
				for (String loc : locations) {
					HashSet<String> states = geonames
							.extractStatesFromQuery(loc);
					for (String state : states) {
						Integer count = stateCounts.get(state);
						if (count == null) {
							stateCounts.put(state, 1);
						} else
							stateCounts.put(state, count + 1);
					}
				}

			}
		}
		MapSorter<String, Integer> ms = new MapSorter<String, Integer>();
		List<Entry<String, Integer>> allStatesRanked = ms.sortMap(stateCounts);
		for (int i = 0; i < allStatesRanked.size(); i++) {
			if (i == N)
				break;
			String state = allStatesRanked.get(i).getKey();
			topStates.put(prefix + i + "_", convertStrToID(state));
		}

		return topStates;
	}

	private static Integer convertStrToID(String str) {
		Integer val = strToIntConverter.get(str);
		if (val != null)
			return val;
		else {
			currentInt = currentInt + 1;
			strToIntConverter.put(str, currentInt);
			return currentInt;

		}
	}

}
